#include "base/log.h"
#include "base/logstream.h"

#include <unistd.h>
#include <sys/syscall.h>

#include "base/thread.h"

namespace net_tools::base
{
  namespace detail
  {

    class Thread_main : util::noncopyable
    {
    public:
      Thread_main(func thread_begin_call,
                  util::Count_down_cond *Count_cond,
                  std::string *thread_name)
          : thread_begin_call_(std::move(thread_begin_call)),
            Count_cond_(Count_cond),
            thread_name_(thread_name){};
      void Start()
      {
        base::Thread::InitThreadtid();
        base::Thread::InitThreadname(thread_name_);
        net_tools::Log::logstream_ = new net_tools::base::Logstream((int)syscall(SYS_gettid));
        NT_LOG_TRACE << "THREAD CREAT NAME:" << *thread_name_ << NT_LOG_ENDL;
        Count_cond_->Signal();
        thread_begin_call_();
      };

    private:
      func thread_begin_call_;
      util::Count_down_cond *Count_cond_;
      std::string *thread_name_;
    };

  } // namespace detail

  __thread unsigned int Thread::thread_tid_ = 0;
  __thread std::string *Thread::p_thread_name_ = nullptr;

  void *Start_thread(void *obj)
  {
    detail::Thread_main *Thread_main_ = reinterpret_cast<detail::Thread_main *>(obj);
    Thread_main_->Start();
    delete Thread_main_;
    return nullptr;
  };

  Thread::Thread(func thread_begin_call, std::string thread_name)
      : threadid_(0),
        thread_begin_call_(std::move(thread_begin_call)),
        Count_cond_(1),
        thread_name_(new std::string(thread_name)){};

  void Thread::Start()
  {
    detail::Thread_main *thread_main_ = new detail::Thread_main(std::move(thread_begin_call_), &Count_cond_, thread_name_);
    pthread_create(&threadid_,
                   NULL,
                   &Start_thread,
                   thread_main_);
    Count_cond_.Wait();
  };

  void Thread::InitThreadtid()
  {
    thread_tid_ = syscall(SYS_gettid);
  };
  void Thread::InitThreadname(std::string *thread_name)
  {
    p_thread_name_ = thread_name;
  };

} //namespace net_tools::base